<?php
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0

 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 */

require_once("AlfaConfiguration.php");
require_once("core/loader/AlfaLoader.php");

/**
 * AlfaApplication - The main class of AlfaWeb framework
 * Loads the controller, executes the proper method, and renders the view.
 *
 * @package     AlfaWeb
 * @author      Alecsandru Gabriel DINU <allecsro@yahoo.com>
 * @license     http://www.apache.org/licenses/LICENSE-2.0.html LGPL
 * @since       1.0
 */
class AlfaApplication {
    private $ctx;
    private $ldr;
    private $devMode;  // is the application running in development mode ?

    /**
     * Performs initialization
     */
    public function init() {
        // register loaders
        spl_autoload_register(array('AlfaLoader', 'autoload'));

        $config = AlfaConfiguration::getInstance();
        $this->devMode = $config->getBoolean("webapp/devMode", $this->devMode);

        // create context
        $this->ctx = $this->getContext();

        // initialize translator
        $trn = AlfaTranslator::getInstance();
        $trn->init($this->ctx);

        // init database
        if ($config->getString("database/orm") == 'propel') {
            PropelTemplate::getInstance();
        } else if ($config->getString("database/orm") == 'ezpdo') {
            EzpdoTemplate::getInstance();
        } else if ($config->getString("database/orm") == 'doctrine') {
            new DoctrineTemplate();
        }

        // initialize bean loader
        AlfaBeanLoader::getInstance();
        ScriptTimer::timing_milestone("finished init");
    }

    /**
     * Executes a request
     */
    public function execute() {
        try {
            session_name('phpalfa');
            session_start();

            $filterChain = new AlfaFilterChain();
            $filterChain->doFilter($this->getContext());
        } catch (Exception $e) {
            $log = Logger::getInstance()->getLogger();
            $log->error($e->getTraceAsString());
            self::exceptionHandler($e);
        }
    }

    /**
     * Returns the webroot of the application
     */
    public static function getAppRoot() {
        $appRoot = AlfaConfiguration::getInstance()->getString("appRoot");
        if (!StringUtils::endsWith('/', $appRoot)) {
            $appRoot = $appRoot . '/';
        }
        return $appRoot;
    }

    /**
     * Returns the webroot of the core app
     */
    public static function getCoreRoot() {
        $appCoreRoot = AlfaConfiguration::getInstance()->getString("appCoreRoot");
        if (!StringUtils::endsWith('/', $appCoreRoot)) {
            $appCoreRoot = $appCoreRoot . '/';
        }
        return $appCoreRoot;
    }

    /**
     * Returns the context
     * @return Context
     */
    private function getContext() {
        if (!$this->ctx) {
            $this->ctx = $this->createContext();
        }
        return $this->ctx;
    }

    /**
     * Create a context
     * @return Context
     */
    private function createContext() {
        $ctx = new Context($this->getAppRoot());
        return $ctx;
    }

    /**
     * A default URL for the app'
     * @return string
     */
    private function getDefaultUrl() {
        $config = AlfaConfiguration::getInstance();
        $result = $config->get('webapp/defaultURL');
        if (sizeof($result) != 1) {
            throw new ConfigurationException("The entry webapp/defaultURL is missing in configuration file.");
        }
        $url = $result[0];
        return $url;
    }

    /**
     * Displays the core exceptions
     */
    public static function exceptionHandler($e) {
        $exception = $e;
        $templateEngine = new AlfaSmartyTemplateEngine("blank.html", "error.htm");
        $templateEngine->mergeField("exception", $e);
        $templateEngine->show();
    }
}

